if unit.target.is_custom_build() {
return Ok(ret);
}
- ret.extend(dep_build_script(unit));
+ ret.extend(dep_build_script(cx, unit));
// If this target is a binary, test, example, etc, then it depends on
// the library of the same package. The call to `resolve.deps` above
if !unit.target.linkable() || unit.pkg.manifest().links().is_none() {
return None;
}
- dep_build_script(unit)
+ dep_build_script(cx, unit)
})
.chain(Some((
new_unit(
}
// Be sure to build/run the build script for documented libraries as
- ret.extend(dep_build_script(unit));
+ ret.extend(dep_build_script(cx, unit));
// If we document a binary, we need the library available
if unit.target.is_bin() {
/// script itself doesn't have any dependencies, so even in that case a unit
/// of work is still returned. `None` is only returned if the package has no
/// build script.
-fn dep_build_script<'a>(unit: &Unit<'a>) -> Option<(Unit<'a>, ProfileFor)> {
+fn dep_build_script<'a>(cx: &Context, unit: &Unit<'a>) -> Option<(Unit<'a>, ProfileFor)> {
unit.pkg
.targets()
.iter()
.map(|t| {
// The profile stored in the Unit is the profile for the thing
// the custom build script is running for.
- // TODO: Fix this for different profiles that don't affect the
- // build.rs environment variables.
(
Unit {
pkg: unit.pkg,
target: t,
- profile: unit.profile,
+ profile: cx.profiles.get_profile_run_custom_build(&unit.profile),
kind: unit.kind,
mode: CompileMode::RunCustomBuild,
},
// environment variables. Note that the profile-related environment
// variables are not set with this the build script's profile but rather the
// package's library profile.
+ // NOTE: If you add any profile flags, be sure to update
+ // `Profiles::get_profile_run_custom_build` so that those flags get
+ // carried over.
let to_exec = to_exec.into_os_string();
let mut cmd = cx.compilation.host_process(to_exec, unit.pkg)?;
cmd.env("OUT_DIR", &build_output)
profile
}
+ /// The profile for *running* a `build.rs` script is only used for setting
+ /// a few environment variables. To ensure proper de-duplication of the
+ /// running `Unit`, this uses a stripped-down profile (so that unrelated
+ /// profile flags don't cause `build.rs` to needlessly run multiple
+ /// times).
+ pub fn get_profile_run_custom_build(&self, for_unit_profile: &Profile) -> Profile {
+ let mut result = Profile::default();
+ result.debuginfo = for_unit_profile.debuginfo;
+ result.opt_level = for_unit_profile.opt_level;
+ result
+ }
+
/// This returns a generic base profile. This is currently used for the
/// `[Finished]` line. It is not entirely accurate, since it doesn't
/// select for the package that was actually built.
for kind in [Kind::Host, Kind::Target].iter() {
for mode in CompileMode::all_modes() {
for profile_for in ProfileFor::all_values() {
- let profile = profiles.get_profile(
- &pkg.name(),
- ws.is_member(pkg),
- *profile_for,
- *mode,
- opts.release,
- );
+ let profile = if mode.is_run_custom_build() {
+ profiles.get_profile_run_custom_build(&profiles.get_profile(
+ &pkg.name(),
+ ws.is_member(pkg),
+ *profile_for,
+ CompileMode::Build,
+ opts.release,
+ ))
+ } else {
+ profiles.get_profile(
+ &pkg.name(),
+ ws.is_member(pkg),
+ *profile_for,
+ *mode,
+ opts.release,
+ )
+ };
units.push(Unit {
pkg,
target,